package com.lingx.web.api;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.lingx.service.LingxService;
import com.lingx.utils.TokenUtils;
import com.lingx.utils.Utils;


@Component
public class ApiService {

	public static ConcurrentMap<Integer,ApiBean> API_CACHE=new ConcurrentHashMap<Integer,ApiBean>();
	private final static Logger logger = LoggerFactory.getLogger(ApiService.class);
	@Resource
	private List<IApi> listApi;
	@Resource
	private JdbcTemplate jdbcTemplate;
	@Resource
	private LingxService lingxService;
	
	@PostConstruct
	public void init() {
		//默认给超管角色授权所有API
		String roleId=lingxService.getConfigValue("lingx.super.role.code", "6e0362e8-100e-11e5-b7ab-74d02b6b5f61");//lingx.super.role.code
		int apicode=0;
		for(IApi api:this.listApi) {
			apicode=api.getApiCode();
			//System.out.println(apicode+":"+api.getApiName()+"-"+api.getGroupName());
			if(this.jdbcTemplate.queryForObject("select count(*) from tlingx_role_api where role_id=? and apicode=?", Integer.class,roleId,String.valueOf(apicode))==0) {
				this.jdbcTemplate.update("insert into tlingx_role_api(id,role_id,apicode)values(?,?,?)",this.lingxService.uuid(),roleId,String.valueOf(apicode));
			}
		}
	}
	
	public Map<String,Object> callApi(Map<String,Object> params){
		if(!params.containsKey("apicode")) {
			return IApi.getRetMap(-1, "请求参数apicode不可为空");
		}
		long stime=System.currentTimeMillis();
		String token=IApi.getParamString(params, "lingxtoken", null);
		Map<String,Object> ret=null;
		IApi apiTemp=null;
		String isLogFile=lingxService.getConfigValue("lingx.apiserver.islogfile", "false");
		try {
			for(IApi api:this.listApi) {
				if(api.getApiCode()==Integer.parseInt(params.get("apicode").toString())) {
					apiTemp=api;
					int errorCode=api.before(params);
					if(errorCode==0) {
						if("true".equals(isLogFile))logger.info(JSON.toJSONString(params));
						ret=api.api(params);
						long time=System.currentTimeMillis()-stime;
						ApiBean bean=API_CACHE.get(api.getApiCode());
						if(bean==null) {
							bean=new ApiBean(api.getApiCode(),api.getApiName(),api.getGroupName(),api.isLog());
							API_CACHE.put(api.getApiCode(), bean);
						}

						bean.getTotal().addAndGet(1);
						if(time>bean.getMaxTime())bean.setMaxTime(time);
						bean.setLastTime(time);
						if("true".equals(isLogFile))logger.info(JSON.toJSONString(ret));
						String ip=IApi.getParamString(params, "X-Real-IP", "");
						if(api.isLog()&&Utils.isNotNull(token)) {
							String userid=TokenUtils.getTokenDataUserId(token);
							this.lingxService.logOperate("api",userid, api.getApiCode()+"-"+api.getApiName(), ip,params, JSON.toJSONString(ret),time);
						}
						break;
					}else {
						ret= IApi.getRetMap(errorCode, "无权限");
					}
					
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			ret= IApi.getRetMap(-1, "接口异常:"+e.getLocalizedMessage());
			System.out.println("接口异常:"+e.getLocalizedMessage());
			logger.info("接口异常:"+e.getLocalizedMessage(), e);
			logger.error("接口异常:"+e.getLocalizedMessage(), e);
			int apicode=Integer.parseInt(params.get("apicode").toString());
			ApiBean bean=API_CACHE.get(apicode);
			if(bean==null) {
				API_CACHE.put(apicode, new ApiBean(apicode,apiTemp.getApiName(),apiTemp.getGroupName(),apiTemp.isLog()));
			}else {
				bean.getTotal().addAndGet(1);
				bean.setErrorNum(bean.getErrorNum()+1);
			}
		}
		if(ret==null) {
			ret= IApi.getRetMap(-1, params.get("apicode")+"接口未实现");
		}
		
		return ret;
	}
	
	/**
	 * 内部直接调用，不需要验证
	 * @param params
	 * @return
	 */
	public Map<String,Object> callApiByLingx(Map<String,Object> params){
		if(!params.containsKey("apicode")) {
			return IApi.getRetMap(-1, "请求参数apicode不可为空");
		}
		Map<String,Object> ret=null;
		try {
			for(IApi api:this.listApi) {
				if(api.getApiCode()==Integer.parseInt(params.get("apicode").toString())) {
					ret=api.api(params);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			ret= IApi.getRetMap(-1, params.get("apicode")+"接口异常:"+e.getLocalizedMessage());
		}
		if(ret==null) {
			ret= IApi.getRetMap(-1, params.get("apicode")+"接口未实现");
		}
		return ret;
	}
	
	
}
